/* Janus Chat - Version 1.0
 * Authors: Matthew Perry
 *          Michael Freid
 *          Marc Latou
 *          Richard Lee
 *
 * The Janus Chat Client is a highly secured
 * peer-to-peer chat client designed to facilitate
 * the transfer of sensitive data or as a communication
 * medium for the extra paranoid
 *
 * This version is written by Matt Perry in an attempt
 * to get a strong base for the project moving forward */

#include<iostream>
#include<string>
#include<stdlib.h>

//Thread library
#include<pthread.h>

//Our Libraries
#include "lib/message.h"
#include "lib/socket.h"
#include "lib/serversocket.h"
#include "lib/exceptions.h"

// DEFINITIONS
#define MAX_INPUT_SIZE 1000

using namespace std;

void connect();
void quit();
char userCmd();
string readInput(string*& overflow); // returns a string with user input up to MAX_INPUT_SIZE characters with the remainder being put dynamically allocated using the pointer overflow that is passed by reference, overflow is set to NULL if no remainder 

void* listenThread( void* info )
{
    try
    {
        ServerSocket servsock;
        cout << "Listening on port: " << servsock.getPort() << endl;

        Socket sock = servsock.acceptSocket();

        cout << endl << "You are recieving a message from ";
        cout << sock.getAddr() << "." << endl;
        cout << sock.getPort() << endl;

        Message msg = sock.recvMsg();

        /*cout << msg.getMoniker() << " says ";
        cout << msg.getBody() << endl;*/
        char* ch = msg.toChar();
        for( int i = 0; i < Message::MAX_SIZE; ++i )
            cout << (int)ch[i] << "|";
        cout << endl;
    }
    catch( BaseException* e )
    {
        cout << e->what() << endl;
    }
}

int main()
{
    //Output nice welcome message
    cout << "Welcome to the Janus Chat Client!" << endl;

    pthread_t listen;
    pthread_create( &listen, NULL, listenThread, NULL );

    while( 1 ) //Loop until user quits
    {
        //Read user command
        char input = userCmd();

        //Act on the user's command
        if( input == 'c' ) connect();
        if( input == 'q' ) quit();
    }

    /*User u;
    u.setUserMoniker( "m.perry" );
    cout << u.getUserMoniker() << endl;
    string longStr( 51, 'a' );
    u.setUserMoniker( longStr );
    cout << u.getUserMoniker() << endl;
    u.setUserMoniker( "m-perry" );
    cout << u.getUserMoniker() << endl;*/

    return 0;    
}

void connect()
{
    /*string ipAddr;
    int port;

    cout << "Please enter the information for the user you would like to connect to:" << endl
         << "IP Address: ";
    cin >> ipAddr;
    cout << "Port: ";
    cin >> port;

    Socket sock;
    try
    {
        sock.connectTo( ipAddr, port );
    }
    catch( BaseException* e )
    {
        cerr << e->what() << endl;
        return;
    }

    string message;
    cout << "Connected to " << ipAddr << " enter a message: " << endl << "> ";
    cin >> message;

    Message msg( 1, "mperry", message );
    try
    {
        sock.sendMsg( msg );
    }
    catch( BaseException* e )
    {
        cerr << e->what() << endl;
        return;
    }*/
}

void quit()
{
    cout << "Thank you for using Janus! Good Bye." << endl;
    exit( 0 );
}

char userCmd()
{
    //Show the user their choices
    cout << "Please enter one of the following commands:" << endl
         << "c - connect to user" << endl
         << "q - quit application" << endl << endl << "> ";

    //Accept input from user
    string input;
    bool valid = false;
    do
    {
        cin >> input;
        //Validate input
        if( input.length() != 1 || ( input[0] != 'c' && input[0] != 'q' ) )
            cout << "Invalid command: Please try again." << endl << endl << "> ";
        else
            valid = true;
    } while( !valid );

    return input[0];
}

string readInput(string*& overflow)
{
    string completeInput = "";
    getline(cin, completeInput);
    if(MAX_INPUT_SIZE < completeInput.length())
    {
        int overflowAmount = completeInput.length() - MAX_INPUT_SIZE;
        char* overflowChars = new char[(overflowAmount+1)]; // +1 for null terminator

        completeInput.copy(overflowChars,overflowAmount, MAX_INPUT_SIZE);	
        overflowChars[overflowAmount] = '\0';

        overflow = new string(overflowChars); // this dynamically created string is returned and must be deleted by the calling function after use
        return completeInput.substr(0, MAX_INPUT_SIZE);
    }
    else
    {
        overflow = NULL;
        return completeInput;
    }
}
